package com.rockcypress.common.agent;

import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.OpenSSHConfig;
import com.rockcypress.common.agent.utils.JSchUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.shell.Availability;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
import org.springframework.shell.standard.ShellMethodAvailability;
import org.springframework.shell.standard.ShellOption;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;

/**
 * @author bolin
 * @create 2020-05-12 11:22 上午
 * @desc
 */
@SpringBootApplication
@ShellComponent
public class SSHAgentApplication {

    public static void main(String[] args) {
        SpringApplication.run(SSHAgentApplication.class, args);
    }

    @ShellMethodAvailability()
    synchronized Availability readConfigAvailability() {
        if (JSchUtils.getInstance().getConfigRepository() == null) {
            readConfig(JSchUtils.DEFAULT_CONFIG_FILE);
        }
        return Availability.available();
    }

    @ShellMethod(value = "读取指定的ssh config: 默认读取～/.ssh/config")
    public String readConfig(String file) {
        try {
            JSchUtils.getInstance().setConfigRepository(OpenSSHConfig.parseFile(file));
            JSchUtils.setCurrConfigFile(file);
            return "加载完成:" + file;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "加载失败:" + file;
    }


    @ShellMethod(value = "显示所有支持的Host")
    public List<Object> list() throws Exception {
        OpenSSHConfig openSSHConfig = (OpenSSHConfig) JSchUtils.getInstance().getConfigRepository();
        Field field = openSSHConfig.getClass().getDeclaredField("config");
        field.setAccessible(true);
        Hashtable table = (Hashtable) field.get(openSSHConfig);
        List<Object> list = new ArrayList<>();
        Iterator<Map.Entry> iterator = table.entrySet().iterator();
        while (iterator.hasNext()) {
            list.add(iterator.next().getKey());
        }
        return list;
    }

    @ShellMethod(value = "打开指定通道")
    public Object open(String host) throws JSchException {
        return JSchUtils.connectionByPK(host);
    }

    @ShellMethod(value = "显示所有打开的通道")
    public Object openList() {
        return JSchUtils.getSessionList();
    }

    @ShellMethod(value = "转发数据: host,localPort,remoteHost,remotePort. 示例：forward host 80 [localhost] [80]")
    public Object forward(String host, Integer localPort, @ShellOption(defaultValue = "localhost") String remoteHost, @ShellOption(defaultValue = ShellOption.NULL) Integer remotePort) throws JSchException {
        if (remotePort == null) {
            remotePort = localPort;
        }
        return JSchUtils.forward(host, localPort, remoteHost, remotePort);
    }

    @ShellMethod(value = "获取服务转发列表")
    public Object forwardList(String host) {
        return JSchUtils.getForwardList(host);
    }

    @ShellMethod(value = "关闭指定服务器的转发: host [localPort]")
    public Object close(String host, @ShellOption(defaultValue = ShellOption.NULL) Integer localPort) throws JSchException {
        return JSchUtils.close(host, localPort);
    }

    @ShellMethod(value = "保存到本地")
    public Object save(String host) throws IOException, ClassNotFoundException {
        return JSchUtils.save(host);
    }

    @ShellMethod(value = "加载本地存档")
    public Object load(String host) throws JSchException, IOException, ClassNotFoundException {
        return JSchUtils.load(host);
    }
}
